/*
 ------------------------------------------------------------------------------
 Copyright (C) 2013 Eternal Games.

 This file is part of the GLQuake source code.

 The GLQuake source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The GLQuake source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the GLQuake source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// common.h - miscellaneous functions used in client and server
//


#ifndef __COMMON_H__
#define __COMMON_H__


#include "../shared/shared.h"
#include "memory.h"
#include "fileSystem.h"
#include "cmdSystem.h"
#include "cvarSystem.h"
#include "msgSystem.h"
#include "defManager.h"
#include "parser.h"
#include "protocol.h"
#include "huffman.h"
#include "network.h"
#include "netChan.h"
#include "system.h"
#include "table.h"
#include "wad.h"


#define ENGINE_NAME					"Eternal Tech"
#define ENGINE_VERSION				"Eternal Tech 0.1.0 BETA"

#define CONFIG_FILE					"GLQuake.cfg"

// Default game directory
#define BASE_DIRECTORY				"base"
#define ID1_DIRECTORY				"id1"

// These directories will be ignored by file and directory scanning functions
#define CODE_DIRECTORY				"code"
#define DOCS_DIRECTORY				"docs"
#define SVN_DIRECTORY				".svn"

// The default action will be executed immediately after initialization
#define DEFAULT_ACTION				"TODO"

extern bool					com_initialized;

extern int					com_frameTime;
extern int					com_frameMsec;
extern int					com_frameCount;

extern int					com_timeAll;
extern int					com_timeWaiting;
extern int					com_timeServer;
extern int					com_timeClient;
extern int					com_timeFrontEnd;
extern int					com_timeBackEnd;
extern int					com_timeSound;

extern cvar_t *				com_version;
extern cvar_t *				com_dedicated;
extern cvar_t *				com_paused;
extern cvar_t *				com_developer;
extern cvar_t *				com_logFile;
extern cvar_t *				com_errorInterrupt;
extern cvar_t *				com_fixedTime;
extern cvar_t *				com_timeScale;
extern cvar_t *				com_speeds;
extern cvar_t *				com_clientRunning;
extern cvar_t *				com_serverRunning;
extern cvar_t *				com_timeDemo;
extern cvar_t *				com_maxFPS;

// Prints a message to the console, and possibly to the log file
void			Com_Printf (const char *fmt, ...);

// Like Com_Printf, but only prints the message in developer mode
void			Com_DPrintf (const char *fmt, ...);

// Throws an error and aborts the current frame. If fatal is true, it will quit
// to the system console and wait for the user to terminate the program.
void			Com_Error (bool fatal, const char *fmt, ...);

// Writes key bindings and archive variables to the given config file
void		Com_WriteConfigToFile (const char *name);

// Launches an integrated editor.
// Note that only one editor can be active at a time.
bool		Com_LaunchEditor (const char *name, editorCallbacks_t *callbacks);

// Closes the currently active integrated editor
void		Com_CloseEditor ();

// Returns true if an integrated editor is currently active
bool		Com_IsEditorActive ();

// Called by the client system for left mouse button down events.
// Will perform a callback to let the active editor select an entity for
// editing. The callback function should return true if it wants the client
// system to skip generating game commands for said event.
bool		Com_EditorEvent ();

// Searches for command line parameters that are "set" commands.
// If match is not NULL, only that variable will be looked for.
// If once is true, the command will be removed. This is to keep it from being
// executed multiple times.
void			Com_StartupVariable (const char *match, bool once);

// Checks for "safe" on the command line, which will skip executing config
// files
bool			Com_SafeMode ();

// Runs a complete frame.
// Called from the program's main loop.
void			Com_Frame ();

// Initializes all of the engine subsystems
void			Com_Init (const char *cmdLine);

// Shuts down all of the engine subsystems
void			Com_Shutdown ();

/*
 ==============================================================================

 CLIENT / SERVER SYSTEMS

 ==============================================================================
*/

void			CM_PrintStats ();
void			CM_Init ();
void			CM_Shutdown ();

void			R_DebugAxis (const glqVec3 &origin, const glqMat3 &axis, float size, bool depthTest, int allowInView);
void			R_DebugLine (const glqVec4 &color, const glqVec3 &start, const glqVec3 &end, bool depthTest, int allowInView);
void			R_DebugArrow (const glqVec4 &color, const glqVec3 &start, const glqVec3 &end, float size, bool depthTest, int allowInView);
void			R_DebugBounds (const glqVec4 &color, const glqBounds &bounds, bool depthTest, int allowInView);
void			R_DebugSphere (const glqVec4 &color, const glqSphere &sphere, bool depthTest, int allowInView);
void			R_DebugBox (const glqVec4 &color, const glqVec3 &origin, const glqMat3 &axis, const glqBounds &bounds, bool depthTest, int allowInView);
void			R_DebugCone (const glqVec4 &color, const glqVec3 &apex, const glqVec3 &direction, float apexRadius, float baseRadius, bool depthTest, int allowInView);
void			R_DebugCircle (const glqVec4 &color, const glqVec3 &origin, const glqVec3 &direction, float radius, int steps, bool depthTest, int allowInView);
void			R_DebugFrustum (const glqVec4 &color, const glqVec3 &origin, const glqMat3 &axis, float xMin, float xMax, float yMin, float yMax, float zNear, float zFar, bool depthTest, int allowInView);
void			R_DebugPolygon (const glqVec4 &color, int numPoints, const glqVec3 *points, bool fill, bool depthTest, int allowInView);
void			R_DebugText (const glqVec4 &color, bool forceColor, const glqVec3 &origin, float cw, float ch, const char *text, bool depthTest, int allowInView);

void			Con_Print (const char *text);

void			Key_WriteBindings (fileHandle_t f);
void			Key_Init ();
void			Key_Shutdown ();

bool			CL_CanLaunchEditor (const char *editor);
void			CL_InitAll ();
void			CL_ShutdownAll ();
void			CL_Drop (const char *message);
void			CL_LocalConnect ();
void			CL_ForwardCommandToServer ();

void			CL_Frame (int msec);
void			CL_Init ();
void			CL_Shutdown ();

void			SV_Frame (int msec);
void			SV_Init ();
void			SV_Shutdown (const char *message);


#endif	// __COMMON_H__